﻿using System;
using System.IO;

namespace Rename
{
    class Program
    {
        static void Main(string[] args)
        {
            //string.Join("\n", args).Output();
            //return;
            //args = new[] { "/src", @"C:\Users\Jackie\Documents\ProSp\dds", "/ren", "%name.gif", "/w", "*.gif", "--out", @"C:\Users\Jackie\Documents\ProSp\dds\res" }; //"/help", 
            if (args.Length < 1)
            {
                Menu();
                return;
            }
            var argument = ResolveArgument(args);
            if (argument == null)
            {
                return;
            }
            if (argument.IsHelp)
            {
                Menu();
                return;
            }
            var files = Directory.GetFiles(argument.SourcePath);
            var filter = argument.Filter?.Replace("*", "");
            var targetPath = argument.TargetPath;
            var savePath = string.Empty;
            var isToTarget = !targetPath.IsNullOrEmpty();
            var count = 0;
            if (isToTarget && !Directory.Exists(targetPath))
            {
                Directory.CreateDirectory(targetPath);
            }
            for (int i = 0, fIndex = 0; i < files.Length; ++i)
            {
                var file = files[i];
                var sName = Path.GetFileNameWithoutExtension(file);
                var ext = Path.GetExtension(file);
                if (argument.FilterType != FilterType.All)
                {
                    if (argument.FilterType == FilterType.None && !ext.IsNullOrEmpty())
                    {
                        continue;
                    }
                    if (argument.FilterType == FilterType.Condition && !ext.IsEquals(filter))
                    {
                        continue;
                    }
                }
                savePath = targetPath;
                if (!isToTarget)
                {
                    savePath = Path.GetDirectoryName(file);
                }
                var target = Path.Combine(savePath, argument.TargetName.Replace("%i", (++fIndex).ToString()).Replace("%name", sName).Replace("%ext", ext));
                try
                {
                    if (isToTarget)
                    {
                        File.Copy(file, target, true);
                    }
                    else
                    {
                        File.Move(file, target);
                    }
                    count++;
                }
                catch (Exception ex)
                {
                    $"rename the {file} failure.{ex.Message}".Output();
                }
            }

            $"All the {count} files rename in the folder ({files.Length})".Output();

        }

        static Argument ResolveArgument(string[] args)
        {
            Argument argument = new Argument();
            var res = ResolveArg(argument, args, new[] { "/help", "-help", "--help", "/?" }, (i, arg) =>
             {
                 return argument.IsHelp = (i == 0); // help只能为第一项                 
             });
            if (res)
            {
                return argument;
            }
            res = ResolveArg(argument, args, new[] { "/src", "-src", "--src" }, (i, arg) =>
            {
                if (i < args.Length - 1)
                {
                    arg.SourcePath = args[i + 1];
                    if (!Directory.Exists(arg.SourcePath))
                    {
                        "source path is not exists.".Output();
                        return false;
                    }
                    return true;
                }
                else
                {
                    "source path is empty.".Output();
                    return false;
                }
            });
            if (!res)
            {
                return null;
            }
            res = ResolveArg(argument, args, new[] { "/out", "-out", "--out" }, (i, arg) =>
            {
                if (i < args.Length - 1)
                {
                    arg.TargetPath = args[i + 1];
                    if (!Directory.Exists(arg.TargetPath) && !Directory.Exists(Path.GetDirectoryName(arg.TargetPath)))
                    {
                        "target path is not exists.".Output();
                        return false;
                    }
                    return true;
                }
                else
                {
                    "target path is empty. use the current path".Output();
                    return true;
                }
            });
            if (!res)
            {
                return null;
            }
            res = ResolveArg(argument, args, new[] { "/ren", "-ren", "--ren" }, (i, arg) =>
            {
                if (i < args.Length - 1)
                {
                    //arg.SourceName = args[i + 1];
                    arg.TargetName = args[i + 1];
                    return true;
                }
                else
                {
                    "the target filename can not be empty.".Output();
                    return false;
                }
            });
            if (!res)
            {
                return null;
            }
            res = ResolveArg(argument, args, new[] { "/w", "-w", "--w" }, (i, arg) =>
            {
                if (i < args.Length - 1)
                {
                    arg.Filter = args[i + 1];
                    if (arg.Filter.IsEquals("none"))
                    {
                        arg.FilterType = FilterType.None;
                    }
                    else if (arg.Filter.IsEquals("*.*"))
                    {
                        arg.FilterType = FilterType.All;
                    }
                    else
                    {
                        arg.FilterType = FilterType.Condition;
                    }
                    return true;
                }
                else
                {
                    "the filter unspecify will be ignore.".Output();
                    return true;
                }
            });

            return argument;
        }

        static bool ResolveArg(Argument argument, string[] args, string[] argNames, Func<int, Argument, bool> deal)
        {
            for (int i = 0; i < args.Length; i++)
            {
                var arg = args[i];
                if (arg.IsEquals(argNames))
                {
                    return deal(i, argument);
                }
            }
            return false;
        }

        static void Menu()
        {
            "==========================================================".Output();
            "parameter help:".Output();
            "/src:the source path".Output();
            "/out:the result save the the path(empty for current)".Output();
            "/w:only do the extension for the /w specify in the source path(*.* for all the file,*.jpg only for the jpg file,none for the no extension files)".Output();
            //"/ren:sourcefile targetfile(rename the source file to the %tf filename,without the path,filename only.\r\ncan use the %i for the number index.)".Output();
            "/ren:targetfilename(rename the source file to the targetfilename,without the path,filename only.\r\ncan use the %i for the number index.\n%name for the source filename,%ext for the source file extension)".Output();
            "eg.".Output();
            "  /src d:/files /ren %name%i%ext /w *.jpg(the jpg file in the D:/files will be rename for: a.jpg => a1.jpg)".Output();
            "  /src d:/files /ren %name%i.jpg /w none(the none extension file in the D:/files will be rename for: a => a1.jpg)".Output();
            "  /src d:/files /ren %name%i.jpg /w none /out D:/refiles (the none extension file in the D:/files will be rename to D:/refiles for: a => a1.jpg)".Output();
        }


    }
}
